package com.metagurukul.metagranth.model.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

import com.metagurukul.metagranth.exception.MetaSqlException;
import com.metagurukul.metagranth.model.common.connection.ConnectionPoolFactory;
import com.metagurukul.metagranth.model.common.dbutil.Util;
import com.metagurukul.metagranth.vo.Tag;
/**
 * 
 * @author team metaGranth
 * This class will deal with the tag table....all operations like insertion,searching operation of the tag table are done here
 *
 */
public class TagDAO {
	/**
	 * 
	 * @param tagObject stores the value object of the tag class which is to be saved in the database
	 * @return tagId of the tag which has been inserted in the database
	 * @throws MetaSqlException
	 */
	public static int save(Tag tagObject)throws MetaSqlException {
		//create and retrieve the connection from the  ConnectionPoolFactory class
		ConnectionPoolFactory cp = ConnectionPoolFactory.getInstance();
		Connection con = cp.checkOut();
		
		String tagName = tagObject.getTagName();
		String query = "Insert into METACUBEGRANTH_TAG(TAG_NAME) values(?)";
		int tagId = 0;
		
		PreparedStatement ps = null;
		try {
			ps = con.prepareStatement(query, ps.RETURN_GENERATED_KEYS);
			//set the prepared statement
			ps.setString(1, tagName);
			ps.executeUpdate();
			ResultSet rs = ps.getGeneratedKeys();
			if(rs.next()){
				tagId=rs.getInt(1);
			}
		} catch (SQLException e) {
			//if there is any sql exception  then the exception is thrown
			throw new MetaSqlException(e);
		} finally {
			//close all the open database connection
			Util.closePreparedStatement(ps);
			//checkIn the connection again to the ConnectionPoolFactory
			 cp.checkIn(con);
		}
		return tagId;
	}
	
	/**
	 * 
	 * @param tag stores the tag value object which is used to search for the tags matching it
	 * @return	arrayList of the tag value objects
	 * all the tags which are like the tag provided by the user is retrieved from the database and is send to jsp for displaying the tags
	 * @throws MetaSqlException
	 */
	public static ArrayList<Tag> searchByTag(Tag tag)throws MetaSqlException {
		//searchSet stores the list of the tag value objects
		ArrayList<Tag> searchSet = new ArrayList<Tag>();
		//create and retrieve the connection from the ConnectionPoolFactory
		ConnectionPoolFactory cp = ConnectionPoolFactory.getInstance();
		Connection con = cp.checkOut();
		
		String tagName = tag.getTagName();
		
		String query = "select * from METACUBEGRANTH_TAG where TAG_NAME like ?";
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			ps = con.prepareStatement(query);
			/* set variable in prepared statement */
			ps.setString(1, "%" + tagName + "%");
			 rs = ps.executeQuery();
			searchSet=processResultSet(rs);
			
		} catch (SQLException e) {
			//if there is any sql exception  then the exception is thrown
			throw new MetaSqlException(e);
		} finally {
			//close all the open database connection
			Util.closePreparedStatement(ps);
			//checkIn the connection again to the ConnectionPoolFactory
			 cp.checkIn(con);
		}
		
		return searchSet;
	}
	
	
	/**
	 * 
	 * @return all the tags present in the database
	 * @throws MetaSqlException
	 */
	public static ArrayList<Tag> getTagsList()throws MetaSqlException {
		//tagsList is the list which will store the tag value objects
		ArrayList<Tag> tagsList = new ArrayList<Tag>();
		//create and retrieve the connection from the ConnectionPoolFactory
		ConnectionPoolFactory cp = ConnectionPoolFactory.getInstance();
		Connection con = cp.checkOut();
		
		String query = "SELECT * FROM METACUBEGRANTH_TAG";
		Statement stmt = null;
		ResultSet rs = null;
		try {
			stmt = con.createStatement();
			rs = stmt.executeQuery(query);
			tagsList = processResultSet(rs);
		} catch (SQLException e) {
			//if there is any sql exception  then the exception is thrown
			throw new MetaSqlException(e);
		} finally {
			//close all the open database connection
			Util.closeStatement(stmt);
			//checkIn the connection again to the ConnectionPoolFactory
			 cp.checkIn(con);
		}
		return tagsList;
	}
	
	/**
	 * 
	 * @param tag stores the value object of the tag class
	 * @return the count of the questions corresponding to a particular tag
	 * 	 * @throws MetaSqlException
	 */
	public static int getTagCountByTag(Tag tag)throws MetaSqlException {
		//create and retrieve the connection from the ConnectionPoolFactory
		ConnectionPoolFactory cp = ConnectionPoolFactory.getInstance();
		Connection con = cp.checkOut();
		
		int tagId=tag.getTagid();
		
		String query = "SELECT COUNT(QUESTION_IDENTIFICATION_NUMBER) FROM METACUBEGRANTH_QUESTION_TAG WHERE TAG_IDENTIFICATION_NUMBER="+tagId+ " group by TAG_IDENTIFICATION_NUMBER";
		Statement stmt = null;
		ResultSet rs = null;
		//stores the tag count
		int tagCount=0;
		try {
			
			stmt = con.createStatement();
			rs = stmt.executeQuery(query);
			if(rs.next()){
				tagCount=rs.getInt(1);
			}
		} catch (SQLException e) {
			//if there is any sql exception  then the exception is thrown
			throw new MetaSqlException(e);
		} finally {
			//close all the open database connection
			Util.closeStatement(stmt);
			//checkIn the connection again to the ConnectionPoolFactory
			 cp.checkIn(con);
		}
		return tagCount;
	}
	
	/**
	 * 
	 * @param questionId stores the question_identification_number
	 * @return	list of the tag value object
	 * this function will return all the tag of a particular question
	 * @throws MetaSqlException
	 */
	public static ArrayList<Tag> getTagsByQuestionId(int questionId)throws MetaSqlException {
		ArrayList<Tag> tagsList = new ArrayList<Tag>();
		//crate and retrieve the connection from the ConnectionPoolFactory
		ConnectionPoolFactory cp = ConnectionPoolFactory.getInstance();
		Connection con = cp.checkOut();
		
		String query = "SELECT * FROM METACUBEGRANTH_TAG WHERE TAG_IDENTIFICATION_NUMBER IN (SELECT TAG_IDENTIFICATION_NUMBER FROM METACUBEGRANTH_QUESTION_TAG WHERE QUESTION_IDENTIFICATION_NUMBER="+questionId+")";
		Statement stmt = null;
		ResultSet rs = null;
		try {
			stmt = con.createStatement();
			rs = stmt.executeQuery(query);
			
			tagsList = processResultSet(rs);
		} catch (SQLException e) {
			//if there is any sql exception  then the exception is thrown
			throw new MetaSqlException(e);
		} finally {
			//close all the open database connection
			Util.closeStatement(stmt);
			//checkIn the connection again to the ConnectionPoolFactory
			 cp.checkIn(con);
		}
		return tagsList;
	}
	
	/**
	 * 
	 * @param rs stores the result set object retrieved after the query has been executed
	 * @return	the list of the tag value objects
	 * this function will create the list of the tag value objects
	 * @throws MetaSqlException
	 */
	private static ArrayList<Tag> processResultSet(ResultSet rs)throws MetaSqlException {
		ArrayList<Tag> tagsList = new ArrayList<Tag>();
		Tag tag = null;
		try {
			while (rs.next()) {
				tag = new Tag();
				tag.setTagid(rs.getInt(1));
				tag.setTagName(rs.getString(2));
				tagsList.add(tag);
			}
		} catch (SQLException e) {
			//if there is any sql exception  then the exception is thrown
			throw new MetaSqlException(e);
		}
		return tagsList;
	}
	
	/**
	 * 
	 * @param tempTag stores the tag name
	 * @return the tag identification number of a particular tag name
	 * @throws MetaSqlException
	 */
	public static int getTagIdByTagName(String tempTag) throws MetaSqlException {
		//create and retrieve the connection from the ConnectionPoolFactory
		ConnectionPoolFactory cp = ConnectionPoolFactory.getInstance();
		Connection con = cp.checkOut();
		
		String query = "SELECT * FROM METACUBEGRANTH_TAG WHERE TAG_NAME LIKE '"+tempTag+"'";
		Statement stmt = null;
		
		int tagId=0;
		ResultSet rs = null;
		try {
			stmt = con.createStatement();
			rs = stmt.executeQuery(query);
			if(rs.next()){
				tagId=rs.getInt(1);
			}
		} catch (SQLException e) {
			//if there is any sql exception  then the exception is thrown
			throw new MetaSqlException(e);
		} finally {
			//close all the open database connection
			Util.closeStatement(stmt);
			//checkIn the connection again to the ConnectionPoolFactory
			 cp.checkIn(con);
		}
		return tagId;
	}
}
